package com.zsx.shopping.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zsx.shopping.common.api.product.vo.SkuVO;
import com.zsx.shopping.product.constant.ProductConstant;
import com.zsx.shopping.product.converter.SaleAttrConverter;
import com.zsx.shopping.product.converter.SkuAttrConverter;
import com.zsx.shopping.product.converter.SkuConverter;
import com.zsx.shopping.product.converter.SpuAttrConverter;
import com.zsx.shopping.product.entity.*;
import com.zsx.shopping.product.mapper.*;
import com.zsx.shopping.product.service.SkuService;
import com.zsx.shopping.product.vo.app.GoodsVO;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 *
 */
@Service
public class SkuServiceImpl extends ServiceImpl<SkuMapper, Sku>
    implements SkuService{

    @Resource
    private SkuMapper skuMapper;

    @Resource
    private SaleAttrMapper saleAttrMapper;

    @Resource
    private SpuAttrMapper spuAttrMapper;

    @Resource
    private SpuMapper spuMapper;

    @Resource
    private SkuAttrMapper skuAttrMapper;

    @Resource
    private SkuConverter skuConverter;

    @Resource
    private SaleAttrConverter saleAttrConverter;

    @Resource
    private SpuAttrConverter spuAttrConverter;

    @Resource
    private SkuAttrConverter skuAttrConverter;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public GoodsVO getGoods(Long skuId) {
        String json = (String) stringRedisTemplate.opsForHash().get(ProductConstant.CACHE_GOODS, skuId.toString());
        if (json != null) {
            ObjectMapper objectMapper = new ObjectMapper();
            try {
                return objectMapper.readValue(json, GoodsVO.class);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
        }
        Sku sku = skuMapper.selectById(skuId);
        Spu spu = spuMapper.selectById(sku.getSpuId());
        List<SpuAttr> spuAttrs = spuAttrMapper.selectList(new LambdaQueryWrapper<SpuAttr>().eq(SpuAttr::getSpuId, spu.getId()));
        List<SaleAttr> saleAttrs = saleAttrMapper.selectList(new LambdaQueryWrapper<SaleAttr>().eq(SaleAttr::getSkuId, skuId));
        String detailImages = spu.getDetailImages();
        List<String> ss = saleAttrMapper.getOptionsBySpuId(spu.getId());

        Map<Long, List<String>> options = new HashMap<>();
        for (String s : ss) {
            String[] split = s.split(":");
            Long attrId = Long.valueOf(split[0]);
            List<String> list = Arrays.asList(split[1].split(";"));
            options.put(attrId, list);
        }

        GoodsVO goodsVO = skuConverter.toGoodsVO(sku);
        goodsVO.setDetailImages(detailImages);
        goodsVO.setSaleAttrs(saleAttrConverter.toSaleAttrVOs(saleAttrs));
        goodsVO.setSpuAttrs(spuAttrConverter.toSpuAttrVOs(spuAttrs));
        goodsVO.setOptions(options);

        return goodsVO;
    }

    @Override
    public List<SkuVO> getSkus(List<Long> skuIds) {
        List<Sku> skus = skuMapper.selectBatchIds(skuIds);
        List<SaleAttr> saleAttrs = saleAttrMapper.selectList(new LambdaQueryWrapper<SaleAttr>().in(SaleAttr::getSkuId, skuIds));
        List<SkuAttr> skuAttrs = skuAttrMapper.selectList(new LambdaQueryWrapper<SkuAttr>().in(SkuAttr::getSkuId, skuIds));

        HashMap<Long, List<SaleAttr>> saleAttrsMap = new HashMap<>(skuIds.size());
        for (SaleAttr saleAttr : saleAttrs) {
            if (!saleAttrsMap.containsKey(saleAttr.getSkuId())) {
                saleAttrsMap.put(saleAttr.getSkuId(), new LinkedList<>());
            }
            saleAttrsMap.get(saleAttr.getSkuId()).add(saleAttr);
        }

        HashMap<Long, List<SkuAttr>> skuAttrsMap = new HashMap<>(skuIds.size());
        for (SkuAttr skuAttr : skuAttrs) {
            if (!skuAttrsMap.containsKey(skuAttr.getSkuId())) {
                skuAttrsMap.put(skuAttr.getSkuId(), new LinkedList<>());
            }
            skuAttrsMap.get(skuAttr.getSkuId()).add(skuAttr);
        }

        ArrayList<SkuVO> skuVOs = new ArrayList<>(skuIds.size());
        for (Sku sku : skus) {
            SkuVO skuVO = skuConverter.toSkuVO(sku);
            skuVO.setSaleAttrs(saleAttrConverter.toSaleAttrVOs(saleAttrsMap.get(sku.getId())));
            skuVO.setSkuAttrs(skuAttrConverter.toSkuAttrVOs(skuAttrsMap.get(sku.getId())));
            skuVOs.add(skuVO);
        }

        return skuVOs;
    }

    @Override
    public BigDecimal getTotalPrice(Map<Long, Integer> map) {
        BigDecimal totalPrice = new BigDecimal("0");
        List<Sku> skus = skuMapper.selectBatchIds(map.keySet());
        for (Sku sku : skus) {
            Integer count = map.get(sku.getId());
            totalPrice = totalPrice.add(sku.getPrice().multiply(new BigDecimal(count)));
        }
        return totalPrice;
    }

    @Override
    public void cacheGoods(List<Long> skuIds) {
        HashMap<String, String> map = new HashMap<>();
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            for (Long skuId : skuIds) {
                map.put(skuId.toString(), objectMapper.writeValueAsString(this.getGoods(skuId)));
            }
            stringRedisTemplate.opsForHash().putAll(ProductConstant.CACHE_GOODS, map);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }
}




